package cn.virens.common.spring.annotations;

import cn.virens.common.exception.APIException;
import cn.virens.common.utils.Assert;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.annotation.AnnotationAttributes;

import java.lang.reflect.Method;

public abstract class VirAbstractMethodInterceptor implements MethodInterceptor, InitializingBean {
    protected VirAbstractAnnotationSource mVirAbstractAnnotationSource;

    public void setAnnotationSource(VirAbstractAnnotationSource mVirAbstractAnnotationSource) {
        this.mVirAbstractAnnotationSource = mVirAbstractAnnotationSource;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.isNull(mVirAbstractAnnotationSource);
    }

    /**
     * 获取当前Method
     */
    protected Method getMethod(MethodInvocation invocation) throws APIException {
        return invocation != null ? invocation.getMethod() : null;
    }

    /**
     * 获取当前Class
     */
    protected Class<?> getClass(MethodInvocation invocation) throws APIException {
        if (invocation != null && invocation.getThis() != null) {
            return AopUtils.getTargetClass(invocation.getThis());
        } else {
            return null;
        }
    }

    /**
     * 从AnnotationAttributes中获取另一个AnnotationAttributes
     */
    protected AnnotationAttributes getAttributes(AnnotationAttributes attributes, String key) {
        Object answer = attributes.get(Assert.isNull(key));

        if (answer instanceof AnnotationAttributes) {
            return (AnnotationAttributes) answer;
        } else {
            return null;
        }

    }

    /**
     * 获取AnnotationAttributes属性
     */
    protected AnnotationAttributes findAnnotationAttributes(MethodInvocation invocation) {
        return findAnnotationAttributes(getMethod(invocation), getClass(invocation));
    }

    /**
     * 获取AnnotationAttributes属性
     */
    protected AnnotationAttributes findAnnotationAttributes(Method method, Class<?> targetClass) {
        return mVirAbstractAnnotationSource.findAnnotationAttributes(method, targetClass);
    }
}
